#!/usr/bin/env python3
# Author: Joshua Chen
# Date: 2015-12-23
# Location: Shenzhen
# Desc: merge the local temporary plain branch into the target
# branch, update the 'plain_position' and 'cipher_position' of
# the position record file to the tip of the local cipher branch.
# Remove the local temporary plain branch after merged.

import os, sys
prog_path = os.path.realpath(__file__)
prog_dir  = os.path.dirname(prog_path)
sys.path.insert(0, prog_dir)
import lib

class Merger():
    """ Merge the decrypted change set into the target branch,
    update the 'cipher_position', and then remove the temporary
    branch.
    """
    def __init__(self, remote_branch):
        self.remote_branch = remote_branch
        parts = remote_branch.split('-')    # format: plain-remotename-branchname
        self.remote_name   = parts[1]
        self.orig_branch   = parts[-1]
        self.cipher_branch = 'cipher-%s-%s' % (self.remote_name, self.orig_branch)
        self.cur_branch    = lib.current_branch()

    def merge(self):
        if self.cur_branch != self.orig_branch:
            print('Checkout branch %s, then try again' % self.orig_branch, file=sys.stderr)
            return False
        cur_branch_old_pos = lib.revision_parse(self.cur_branch)
        stat = lib.merge(self.remote_branch)
        if not stat:
            print('Merge failed, solve the problem, and try again', file=sys.stderr)
            return False

        # update the position of the local cipher branch
        rmt_c_branch = 'cipher-%s' % self.orig_branch
        rt_c_branch  = 'refs/remotes/' + self.remote_name + '/' + rmt_c_branch
        sha1 = lib.revision_parse(rt_c_branch)
        reason = "move to %s (%s)" % (rt_c_branch, sha1)
        lib.update_branch(self.cipher_branch, rt_c_branch, reason)
        print('Local cipher branch updated')

        # update the location record
        pos = lib.get_position_record(self.remote_name, self.orig_branch)
        plain_pos = lib.calc_plain_position(cur_branch_old_pos,
                        self.remote_branch, self.cur_branch, pos[0])
        lib.update_position_record(self.remote_name, self.orig_branch,
                        plain_pos, self.cipher_branch)
        print('Position record updated')

        lib.remove_branch(self.remote_branch)
        print('Temporary branch %s removed' % self.remote_branch)
        return True


def help(ofile=sys.stdout):
    """ Show help message
    """
    msg = 'Usage: %s branch' % os.path.basename(sys.argv[0])
    print(msg, file=ofile)


if __name__ == '__main__':
    if not lib.env_ok():
        exit(1)

    if len(sys.argv) < 2:
        help(sys.stderr)
        exit(1)

    branch = sys.argv[1]
    try:
        merger = Merger(branch)
        stat = merger.merge()
        code = 0 if stat else 1
        exit(code)
    except KeyboardInterrupt:
        exit(1)
    except Exception as e:
        print(str(e))
        exit(1)
    else:
        exit(0)
